{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Introduction to TensorFlow, now leveraging tensors!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this notebook, we modify our [intro to TensorFlow notebook](https://github.com/the-deep-learners/TensorFlow-LiveLessons/blob/master/notebooks/point_by_point_intro_to_tensorflow.ipynb) to use tensors in place of our *for* loop. This is a derivation of Jared Ostmeyer's [Naked Tensor](https://github.com/jostmey/NakedTensor/) code. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### The initial steps are identical to the earlier notebook"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "np.random.seed(42)\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "import tensorflow as tf\n",
    "tf.set_random_seed(42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "xs = [0., 1., 2., 3., 4., 5., 6., 7.] \n",
    "ys = [-.82, -.94, -.12, .26, .39, .64, 1.02, 1.] "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nJKnl/wHDphZCP1Xq2gAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f1d90705dd8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots()\n",
    "_ = ax.scatter(xs, ys)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "m = tf.Variable(-0.5)\n",
    "b = tf.Variable(1.0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Define the cost as a tensor -- more elegant than a *for* loop and enables distributed computing in TensorFlow"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "ys_model = m*xs+b\n",
    "total_error = tf.reduce_sum((ys-ys_model)**2) # use an op to calculate SSE across all values instead of one by one"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### The remaining steps are also identical to the earlier notebook!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "optimizer_operation = tf.train.GradientDescentOptimizer(learning_rate=0.001).minimize(total_error)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "initializer_operation = tf.global_variables_initializer()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "with tf.Session() as session:\n",
    "    \n",
    "    session.run(initializer_operation)\n",
    "    \n",
    "    n_epochs = 1000 # 10, then 1000\n",
    "    for iteration in range(n_epochs):\n",
    "        session.run(optimizer_operation)\n",
    "        \n",
    "    slope, intercept = session.run([m, b])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.29314372"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "slope"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-0.84175235"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "intercept"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "y_hat = intercept + slope*np.array(xs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>y</th>\n",
       "      <th>y_hat</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>-0.82</td>\n",
       "      <td>-0.841752</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-0.94</td>\n",
       "      <td>-0.548609</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>-0.12</td>\n",
       "      <td>-0.255465</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.26</td>\n",
       "      <td>0.037679</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.39</td>\n",
       "      <td>0.330823</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>0.64</td>\n",
       "      <td>0.623966</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>1.02</td>\n",
       "      <td>0.917110</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>1.00</td>\n",
       "      <td>1.210254</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      y     y_hat\n",
       "0 -0.82 -0.841752\n",
       "1 -0.94 -0.548609\n",
       "2 -0.12 -0.255465\n",
       "3  0.26  0.037679\n",
       "4  0.39  0.330823\n",
       "5  0.64  0.623966\n",
       "6  1.02  0.917110\n",
       "7  1.00  1.210254"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.DataFrame(list(zip(ys, y_hat)), columns=['y', 'y_hat'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nMGzTZ2pHngAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f1d4650e0f0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots()\n",
    "\n",
    "ax.scatter(xs, ys)\n",
    "x_min, x_max = ax.get_xlim()\n",
    "y_min, y_max = intercept, intercept + slope*(x_max-x_min)\n",
    "\n",
    "ax.plot([x_min, x_max], [y_min, y_max])\n",
    "_ = ax.set_xlim([x_min, x_max])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
